package com.alog.yzd.bookmall.dao.order;

import com.alog.yzd.bookmall.domain.book.Book;
import com.alog.yzd.bookmall.domain.order.Order;
import com.alog.yzd.bookmall.domain.order.OrderItem;
import com.alog.yzd.bookmall.domain.user.User;
import com.alog.yzd.bookmall.pager.Expression;
import com.alog.yzd.bookmall.pager.PageBaen;
import com.alog.yzd.bookmall.pager.PageConstants;
import com.alog.yzd.bookmall.utils.SqlUtil;
import com.alog.yzd.bookmall.utils.jdbc.TxQueryRunner;
import com.alog.yzd.commons.CommonUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class OrderDao {
    private QueryRunner qr = new TxQueryRunner();

    /**
     * 查询用户的订单列表
     * @param pc
     * @return
     * @throws SQLException
     */
    public PageBaen<Order> findByStatus(int status, int pc) throws SQLException {
        List<Expression> expressionList = new ArrayList<>();
        expressionList.add(new Expression("status", "=", status + ""));
        return findByCriteria(expressionList, pc);
    }

    /**
     * 查询所有订单
     * @param pc
     * @return
     * @throws SQLException
     */
    public PageBaen<Order> findAll(int pc) throws SQLException {
        List<Expression> expressionList = new ArrayList<>();
        return findByCriteria(expressionList, pc);
    }

    /**
     * 修改订单状态
     * @param oid
     * @param status
     * @throws SQLException
     */
    public void updateStatus(String oid , int status) throws SQLException {
        String sql = "update t_order set status = ? where oid = ?";
        qr.update(sql, new Object[]{status, oid});
    }
    /**
     * 查询订单状态
     * @param oid
     * @return
     * @throws SQLException
     */
    public int findStatus(String oid) throws SQLException {
        String sql = "select status from t_order where oid = ?";
        Number number = qr.query(sql, new ScalarHandler<>(), oid);
        return number.intValue();
    }

    /**
     * 查询订单
     * @param oid
     * @return
     * @throws SQLException
     */
    public Order load(String oid) throws SQLException {
        String sql = "select * from t_order where oid = ?";
        Map<String, Object> map = qr.query(sql, new MapHandler(), new Object[]{oid});
        Order order = CommonUtils.toBean(map, Order.class);
        User user = CommonUtils.toBean(map, User.class);
        order.setOwner(user);
        loadOrderItem(order);
        return order;
    }

    /**
     * 生成订单
     * @param order
     */
    public void addOrder(Order order) throws SQLException {
        String sql = "insert into t_order(oid, ordertime, total, status, address, uid) values (?,?,?,?,?,?)";
        Object[] params = new Object[]{order.getOid(), order.getOrdertime(), order.getTotal(),
                order.getStatus(), order.getAddress(), order.getOwner().getUid()};
        qr.insert(sql, new ScalarHandler<>(), params);

        sql = "insert into t_orderitem (orderItemId, quantity, subtotal, bid, bname, currPrice, image_b, oid) values (?, ?, ?, ?, ?, ?, ?, ?)";
        int len = order.getOrderItems().size();
        Object[][] objs = new Object[len][];
        int i = 0;
        for(OrderItem item : order.getOrderItems()){
            Object[] obj = new Object[]{item.getOrderItemId(), item.getQuantity(), item.getSubtotal(), item.getBook().getBid(),
                item.getBook().getBname(), item.getBook().getCurrPrice(), item.getBook().getImage_b(), item.getOrder().getOid()};
            objs[i++] = obj;
        }
        qr.batch(sql, objs);
    }


    /**
     * 查询用户的订单列表
     * @param uid
     * @param pc
     * @return
     * @throws SQLException
     */
    public PageBaen<Order> findByUser(String uid, int pc) throws SQLException {
        List<Expression> expressionList = new ArrayList<>();
        expressionList.add(new Expression("uid", "=", uid));
        return findByCriteria(expressionList, pc);
    }
    /**
     * 通用的查询方法
     * @param exprList
     * @param pc
     * @return
     * @throws SQLException
     */
    private PageBaen<Order> findByCriteria(List<Expression> exprList, int pc) throws SQLException {
        //得到ps
        //得到tr
        //得到BeanList
        //创建PageBaen

        int ps = PageConstants.ORDER_PAGE_SIZE;
        List<Object> params = new ArrayList<>();
        String whereSql = SqlUtil.createWhereSql(exprList, params);

        String sql = "select count(*) from t_order " + whereSql;
        Number number = qr.query(sql, new ScalarHandler<>(), params.toArray());
        int tr = number.intValue();

        sql = "select * from t_order " + whereSql + " order by ordertime desc limit ?, ?";
        params.add((pc - 1) * ps);
        params.add(ps);
        List<Order> orderList = qr.query(sql, new BeanListHandler<Order>(Order.class), params.toArray());

        for(Order order : orderList){
            loadOrderItem(order);
        }

        PageBaen<Order> pb = new PageBaen<>();
        pb.setBeanList(orderList);
        pb.setPc(pc);
        pb.setPs(ps);
        pb.setTr(tr);
        return pb;
    }

    /**
     * 加载订单的子条目
     * @param order
     * @throws SQLException
     */
    private void loadOrderItem(Order order) throws SQLException {
        String sql = "select * from t_orderitem where oid = ?";
        List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler(), new Object[]{order.getOid()});
        List<OrderItem> orderItems = toOrderItemList(mapList);
        order.setOrderItems(orderItems);
    }

    /**
     *  映射OrderItemList
     * @param mapList
     * @return
     */
    private List<OrderItem> toOrderItemList(List<Map<String, Object>> mapList){
        List<OrderItem> orderItems = new ArrayList<>();
        for(Map<String , Object> map : mapList){
            OrderItem item = toOrderItem(map);
            orderItems.add(item);
        }
        return orderItems;
    }

    /**
     * 将Map映射成OrderItem
     * @param map
     * @return
     */
    private OrderItem toOrderItem(Map<String , Object> map){
        OrderItem item = CommonUtils.toBean(map, OrderItem.class);
        Book book = CommonUtils.toBean(map, Book.class);
        item.setBook(book);
        return item;
    }
}
